package com.zhiche.lisa.bms.service.invoice.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.qiniu.storage.model.FileInfo;
import com.zhiche.lisa.bms.dao.mapper.fee.FeeAssessmentMapper;
import com.zhiche.lisa.bms.dao.mapper.fee.FeeRewardMapper;
import com.zhiche.lisa.bms.dao.mapper.invoice.InvoiceApplyMapper;
import com.zhiche.lisa.bms.dao.model.fee.FeeAssessment;
import com.zhiche.lisa.bms.dao.model.fee.FeeReward;
import com.zhiche.lisa.bms.dao.model.invoice.InvoiceApply;
import com.zhiche.lisa.bms.dao.model.invoice.InvoiceApplyAccy;
import com.zhiche.lisa.bms.dao.model.invoice.InvoiceApplyAsse;
import com.zhiche.lisa.bms.dao.model.invoice.InvoiceReg;
import com.zhiche.lisa.bms.dao.model.receipt.ReceiptAffirm;
import com.zhiche.lisa.bms.dao.model.receipt.ReceiptAffirmDtl;
import com.zhiche.lisa.bms.enums.InvoiceAssesTypeEnum;
import com.zhiche.lisa.bms.pojo.dto.util.BmsServiceResult;
import com.zhiche.lisa.bms.pojo.dto.util.InvoiceApplyDTO;
import com.zhiche.lisa.bms.pojo.dto.util.InvoiceRegDTO;
import com.zhiche.lisa.bms.pojo.dto.util.LspBasicDTO;
import com.zhiche.lisa.bms.pojo.vo.invoice.InvoiceApplyAndAsseBillDetailVO;
import com.zhiche.lisa.bms.pojo.vo.invoice.InvoiceApplyExcelVO;
import com.zhiche.lisa.bms.service.fee.FeeAssessmentService;
import com.zhiche.lisa.bms.service.fee.FeeRewardService;
import com.zhiche.lisa.bms.service.invoice.*;
import com.zhiche.lisa.bms.service.receipt.ReceiptAffirmService;
import com.zhiche.lisa.bms.service.utils.LspUtil;
import com.zhiche.lisa.bms.service.utils.OtmUtil;
import com.zhiche.lisa.bms.service.utils.common.UploadUtil;
import com.zhiche.lisa.bms.service.utils.common.identityCodeUtil.CodeUtil;
import com.zhiche.lisa.bms.utils.ToolCommonUtils;
import com.zhiche.lisa.core.supports.BaseException;
import com.zhiche.lisa.core.utils.qiniu.util.QiniuUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 申请开票主表 服务实现类
 * </p>
 *
 * @author liuanshun
 * @since 2018-09-27
 */
@Service
@Slf4j
public class InvoiceApplyServiceImpl extends ServiceImpl<InvoiceApplyMapper, InvoiceApply> implements InvoiceApplyService {
    @Autowired
    private CodeUtil codeUtil;

    @Autowired
    private InvoiceApplyBillService invoiceApplyBillService;

    @Autowired
    private InvoiceApplyAccyService invoiceApplyAccyService;

    @Autowired
    private InvoiceApplyAsseService invoiceApplyAsseService;

    @Autowired
    private InvoiceRegService invoiceRegService;

    @Autowired
    private ReceiptAffirmService receiptAffirmService;

    @Autowired
    private OtmUtil otmUtil;

    @Autowired
    private LspUtil lspUtil;

    @Autowired
    private FeeRewardMapper feeRewardMapper;

    @Autowired
    private FeeRewardService feeRewardService;

    @Autowired
    private FeeAssessmentMapper feeAssessmentMapper;

    @Autowired
    private FeeAssessmentService feeAssessmentService;

    private EntityWrapper<InvoiceApply> bindInvoiceApplyEntityWrapper(Map<String, Object> condition) {
        EntityWrapper<InvoiceApply> invoiceApplyEntityWrapper = new EntityWrapper<InvoiceApply>();
        invoiceApplyEntityWrapper.orderBy("gmt_create desc, id desc");
        if (!CollectionUtils.isEmpty(condition)) {
            for (Map.Entry<String, Object> entry :
                    condition.entrySet()) {
                if (Objects.nonNull(entry.getValue()) && !StringUtils.isEmpty(entry.getValue())) {
                    //开票申请号
                    if ("code".equals(entry.getKey())) {
                        invoiceApplyEntityWrapper.like("code", entry.getValue().toString());
                    }
                    //状态
                    if ("status".equals(entry.getKey())) {
                        invoiceApplyEntityWrapper.eq("status", entry.getValue());
                    }
                    //登记时间开始
                    if ("registerDateStart".equals(entry.getKey())) {
                        invoiceApplyEntityWrapper.ge("register_date", entry.getValue());
                    }
                    //登记时间结束
                    if ("registerDateEnd".equals(entry.getKey())) {
                        invoiceApplyEntityWrapper.le("register_date", entry.getValue());
                    }
                    //客户
                    if ("client".equals(entry.getKey())) {
                        invoiceApplyEntityWrapper.andNew().eq("client", entry.getValue());
                        invoiceApplyEntityWrapper.or().eq("client_id", entry.getValue());
                    }
                    // 供方公司
                    if ("customerId".equals(entry.getKey())) {
                        invoiceApplyEntityWrapper.eq("customer_id", entry.getValue());
                    }
                    // 开票主键
                    if ("invoiceId".equals(entry.getKey())) {
                        invoiceApplyEntityWrapper.eq("invoice_id", entry.getValue());
                    }
                    // 开票主键-批量
                    if ("invoiceIdArray".equals(entry.getKey())) {
                        String invoiceIdArrayStr = entry.getValue().toString();
                        String[] invoiceIdArray = invoiceIdArrayStr.trim().replace(" ", "").split(",|;|\n");
                        if (invoiceIdArray != null && invoiceIdArray.length > 0) {
                            invoiceApplyEntityWrapper.in("invoice_id", invoiceIdArray);
                        }
                    }
                }
            }
        }
        return invoiceApplyEntityWrapper;
    }

    /**
     * 查询开票分页信息
     *
     * @param invoiceApplyPage
     * @return
     */
    @Override
    public Page<InvoiceApply> selectInvoiceApplyPage(Page<InvoiceApply> invoiceApplyPage) {
        EntityWrapper<InvoiceApply> ew = this.bindInvoiceApplyEntityWrapper(invoiceApplyPage.getCondition());
        return this.selectPage(invoiceApplyPage.setCondition(new HashMap<>()), ew);
    }

    /**
     * 根据申请开票标识获取对应申请开票的详细信息
     *
     * @param invoiceApply
     * @return
     */
    @Override
    public InvoiceApply selectInvoiceApply(InvoiceApply invoiceApply) {
        if (Objects.nonNull(invoiceApply)) {
            return baseMapper.selectOne(invoiceApply);
        }
        return null;
    }

    /**
     * 新增申请账单
     *
     * @param invoiceApply
     */
    @Override
    public void insertInvoiceApply(InvoiceApply invoiceApply) {
        try {
            invoiceApply.setCode(codeUtil.getInvoiceApplyCode().getNextCode(null));
            invoiceApply.setStatus(0);
            invoiceApply.setGmtCreate(new Date());
            this.insert(invoiceApply);
        } catch (BaseException e) {
            throw e;
        } catch (Exception e) {
            throw new BaseException("申请账单开票详明新增异常");
        }
    }

    /**
     * 审核
     *
     * @param invoiceApplyId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void invoiceApplyExamine(Long invoiceApplyId) {
        InvoiceApply invoiceApply = this.selectById(invoiceApplyId);
        if (Objects.isNull(invoiceApply)) throw new BaseException("所申请的开票信息不存在");
        if (new Integer("1").equals(invoiceApply.getStatus())) throw new BaseException("指定信息已被审核");
        invoiceApply.setStatus(1);
        invoiceApply.setAuditDate(new Date());
        this.updateById(invoiceApply);
    }

    /**
     * 批量审核
     *
     * @param invoiceApplyIds
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void invoiceApplyExamineList(Long[] invoiceApplyIds) {
        EntityWrapper<InvoiceApply> invoiceApplyEntityWrapper = new EntityWrapper<>();
        invoiceApplyEntityWrapper.in("id", invoiceApplyIds);
        InvoiceApply invoiceApply = new InvoiceApply();
        invoiceApply.setStatus(1);
        invoiceApply.setAuditDate(new Date());
        baseMapper.update(invoiceApply, invoiceApplyEntityWrapper);
    }

    /**
     * 弃审
     *
     * @param invoiceApplyId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void invoiceApplyDiscardedExamine(Long invoiceApplyId) {
        InvoiceApply invoiceApply = this.selectById(invoiceApplyId);
        if (Objects.isNull(invoiceApply)) throw new BaseException("所申请的开票信息不存在");
        if (new Integer("0").equals(invoiceApply.getStatus())) throw new BaseException("指定信息已被弃审");
        invoiceApply.setStatus(0);
        invoiceApply.setAuditDate(null);
        this.updateAllColumnById(invoiceApply);
    }

    /**
     * 批量弃审
     *
     * @param invoiceApplyIds
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void invoiceApplyDiscardedExamineList(Long[] invoiceApplyIds) {
        EntityWrapper<InvoiceApply> invoiceApplyEntityWrapper = new EntityWrapper<>();
        invoiceApplyEntityWrapper.in("id", invoiceApplyIds);
        InvoiceApply invoiceApply = new InvoiceApply();
        invoiceApply.setStatus(0);
        invoiceApply.setAuditDate(null);
        baseMapper.update(invoiceApply, invoiceApplyEntityWrapper);
    }

    /**
     * 新增申请账单以及绑定详明
     *
     * @param invoiceApplyAndAsseBillDetailVO
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void insertInvoiceApplyAndDetail(InvoiceApplyAndAsseBillDetailVO invoiceApplyAndAsseBillDetailVO) {
        try {
            InvoiceApply invoiceApply = new InvoiceApply();
            BeanUtils.copyProperties(invoiceApplyAndAsseBillDetailVO, invoiceApply);
            invoiceApply.setCode(codeUtil.getInvoiceApplyCode().getNextCode(null));
            invoiceApply.setStatus(0);
            invoiceApply.setGmtCreate(new Date());
            if (invoiceApplyAndAsseBillDetailVO.getCustomerId() != null) {
                LspBasicDTO lspBasicDTO = lspUtil.getLspById(invoiceApplyAndAsseBillDetailVO.getCustomerId());
                if (lspBasicDTO != null) {
                    invoiceApply.setTenantId(lspBasicDTO.getTenantId());
                }
            }
            // 2019-08-22 支付申请号处理
            List<String> payApplyCodeList = invoiceApplyAndAsseBillDetailVO.getPayApplyCodeList();
            if (!CollectionUtils.isEmpty(payApplyCodeList)) {
                String payApplyCodeArray = org.apache.commons.lang3.StringUtils.join(payApplyCodeList, ",");
                invoiceApply.setPayApplyCodeArray(payApplyCodeArray);
            }
            this.insert(invoiceApply);
            // 考核单
            if (!CollectionUtils.isEmpty(invoiceApplyAndAsseBillDetailVO.getInvoiceApplyAsses())) {
                invoiceApplyAsseService.insertInvoiceApplyAsse(invoiceApplyAndAsseBillDetailVO.getInvoiceApplyAsses(),
                        invoiceApply.getId(), InvoiceAssesTypeEnum.INVOICE_ASS.getCode());
                // 更新考核单的bms已执行金额
                updateFeeAssess(invoiceApplyAndAsseBillDetailVO.getInvoiceApplyAsses(), invoiceApply.getInvoiceId());
            }
            // 奖励单
            if (!CollectionUtils.isEmpty(invoiceApplyAndAsseBillDetailVO.getFeeAwardList())) {
                invoiceApplyAsseService.insertInvoiceApplyAsse(invoiceApplyAndAsseBillDetailVO.getFeeAwardList(),
                        invoiceApply.getId(), InvoiceAssesTypeEnum.INVOICE_REWARD.getCode());
                // 更新bms已执行金额
                updateFeepayReward(invoiceApplyAndAsseBillDetailVO.getFeeAwardList(), invoiceApply.getInvoiceId());
            }
            invoiceApplyBillService.insertInvoiceApplyBill(invoiceApplyAndAsseBillDetailVO.getInvoiceApplyBills(), invoiceApply.getId());
        } catch (BaseException e) {
            throw e;
        } catch (Exception e) {
            throw new BaseException("申请账单开票详明新增异常");
        }
    }

    /**
     * 更新考核单的bms执行金额
     *
     * @param feeAssessList
     */
    private void updateFeeAssess(List<InvoiceApplyAsse> feeAssessList, String bmsInvoiceId) {
        // feeAssessmentMapper
        List<FeeAssessment> updateFeeAssessList = Lists.newArrayList();
        for (InvoiceApplyAsse invoiceApplyAsse : feeAssessList) {
            if (invoiceApplyAsse.getCurUseMoney() == null) {
                invoiceApplyAsse.setCurUseMoney(BigDecimal.ZERO);
            }
            if (invoiceApplyAsse != null && !StringUtils.isEmpty(invoiceApplyAsse.getAssessCode())) {
                EntityWrapper<FeeAssessment> ew = new EntityWrapper<>();
                ew.eq("assess_code", invoiceApplyAsse.getAssessCode());
                List<FeeAssessment> assessList = feeAssessmentMapper.selectListNoTenant(ew);
                if (!CollectionUtils.isEmpty(assessList)) {
                    FeeAssessment feeAssessment = assessList.get(0);
                    if (feeAssessment.getBmsSum() != null) {
                        feeAssessment.setBmsSum(feeAssessment.getBmsSum().add(invoiceApplyAsse.getCurUseMoney()));
                    } else {
                        feeAssessment.setBmsSum(invoiceApplyAsse.getCurUseMoney());
                    }
                    // bms执行剩余金额
                    feeAssessment.setBmsBalance(feeAssessment.getAmount().subtract(feeAssessment.getBmsSum()));
                    // 更新开票申请id
                    if (!StringUtils.isEmpty(bmsInvoiceId)) {
                        if (!StringUtils.isEmpty(feeAssessment.getBmsInvoiceId())) {
                            // 判断 是否存在
                            if (!feeAssessment.getBmsInvoiceId().contains(bmsInvoiceId)) {
                                feeAssessment.setBmsInvoiceId(feeAssessment.getBmsInvoiceId() + "; " + bmsInvoiceId);
                            }
                        } else {
                            // 直接更新
                            feeAssessment.setBmsInvoiceId(bmsInvoiceId);
                        }
                    }
                    updateFeeAssessList.add(feeAssessment);
                }
            }
        }
        if (!CollectionUtils.isEmpty(updateFeeAssessList)) {
            feeAssessmentService.updateBatchById(updateFeeAssessList);
        }
    }

    /**
     * 更新奖励单已执行金额
     *
     * @param feeAwardList
     */
    private void updateFeepayReward(List<InvoiceApplyAsse> feeAwardList, String bmsInvoiceId) {
        List<FeeReward> updateRewardList = Lists.newArrayList();
        for (InvoiceApplyAsse invoiceApplyAsse : feeAwardList) {
            if (invoiceApplyAsse.getCurUseMoney() == null) {
                invoiceApplyAsse.setCurUseMoney(BigDecimal.ZERO);
            }
            if (invoiceApplyAsse != null && !StringUtils.isEmpty(invoiceApplyAsse.getAssessCode())) {
                EntityWrapper<FeeReward> ew = new EntityWrapper<>();
                ew.eq("red_code", invoiceApplyAsse.getAssessCode());
                List<FeeReward> feeRewardList = feeRewardMapper.selectListNoTenant(ew);
                if (!CollectionUtils.isEmpty(feeRewardList)) {
                    FeeReward feeReward = feeRewardList.get(0);
                    if (feeReward.getBmsSum() != null) {
                        feeReward.setBmsSum(feeReward.getBmsSum().add(invoiceApplyAsse.getCurUseMoney()));
                    } else {
                        feeReward.setBmsSum(invoiceApplyAsse.getCurUseMoney());
                    }
                    // bms执行剩余金额
                    feeReward.setBmsBalance(feeReward.getRedSum().subtract(feeReward.getBmsSum()));
                    // 更新开票申请id
                    if (!StringUtils.isEmpty(bmsInvoiceId)) {
                        if (StringUtils.isEmpty(feeReward.getBmsInvoiceId())) {
                            // 直接更新
                            feeReward.setBmsInvoiceId(bmsInvoiceId);
                        } else {
                            // 判断 是否存在
                            if (!feeReward.getBmsInvoiceId().contains(bmsInvoiceId)) {
                                feeReward.setBmsInvoiceId(feeReward.getBmsInvoiceId() + "; " + bmsInvoiceId);
                            }
                        }
                    }
                    updateRewardList.add(feeReward);
                }
            }

        }
        if (!CollectionUtils.isEmpty(updateRewardList)) {
            feeRewardService.updateBatchById(updateRewardList);
        }
    }

    /**
     * 修改指定列信息
     *
     * @param newInvoiceApply
     */
    @Override
    public void updateInvoiceApplyAppointCloumn(InvoiceApply newInvoiceApply) {
        try {
            //数据存在性校验
            if (Objects.isNull(newInvoiceApply) && Objects.isNull(newInvoiceApply.getId()))
                throw new BaseException("指定信息不存在");
            //获取原始信息
            InvoiceApply invoiceApply = new InvoiceApply();
            //绑定修改指定信息
            invoiceApply.setId(newInvoiceApply.getId());
            invoiceApply.setTaxRate(newInvoiceApply.getTaxRate());
            invoiceApply.setTfn(newInvoiceApply.getTfn());
            invoiceApply.setTrackingNum(newInvoiceApply.getTrackingNum());
            invoiceApply.setRegisterDate(newInvoiceApply.getRegisterDate());
            this.updateById(invoiceApply);
        } catch (BaseException e) {
            log.error("InvoiceApplyServiceImpl.updateInvoiceApplyAppointCloumn error: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("InvoiceApplyServiceImpl.updateInvoiceApplyAppointCloumn error: {}", e.getMessage());
            throw new BaseException("申请账单开票信息编辑失败");
        }
    }

    /**
     * 根据指定申请单推送对应登记附件
     *
     * @param inParm
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void invoiceApplyLicenseConfim(InvoiceApply inParm) {
        /*
         * 获取基本信息
         */
        if (inParm == null || inParm.getId() == null) throw new BaseException("请指定对应支付申请单");
        if (StringUtils.isEmpty(inParm.getTrackingNum())) throw new BaseException("快递单号不存在");
        InvoiceApply invoiceApply = this.selectById(inParm.getId());
        if (invoiceApply == null) throw new BaseException("支付申请单不存在");
        if (new Integer(4).compareTo(invoiceApply.getStatus()) == 0) throw new BaseException("该申请单已被确认");
        List<InvoiceReg> invoiceRegs = invoiceRegService.selectInvoiceRegByHeaderId(inParm.getId());
        List<InvoiceApplyAccy> invoiceApplyAccies = invoiceApplyAccyService.selectInvoiceApplyAccyByHeadId(inParm.getId());
        if (CollectionUtils.isEmpty(invoiceRegs)) throw new BaseException("该申请单无发票信息");
        if (CollectionUtils.isEmpty(invoiceApplyAccies)) throw new BaseException("该申请单无附件信息");
        invoiceApply.setStatus(3);
        invoiceApply.setTrackingNum(inParm.getTrackingNum());
        /*
         * 修改状态
         */
        this.updateById(invoiceApply);
        /*
         * DTO转换
         */
        InvoiceApplyDTO invoiceApplyDTO = new InvoiceApplyDTO();
        invoiceApplyAccies.forEach(invoiceApplyAccy -> {
            if (Objects.deepEquals(invoiceApplyAccy.getAccyType(), 0)) {
                invoiceApplyDTO.setCustBillFile(invoiceApplyAccy.getFileKey() + "$" + invoiceApplyAccy.getFileName());
            } else if (Objects.deepEquals(invoiceApplyAccy.getAccyType(), 1)) {
                invoiceApplyDTO.setOtherFile(invoiceApplyAccy.getFileKey() + "$" + invoiceApplyAccy.getFileName());
            }
        });
        List<InvoiceRegDTO> invoiceRegDTOS = new ArrayList<>();
        invoiceRegs.forEach(invoiceReg -> {
            /*
             * 根据key获取下载链接
             */
//            AttachDetailVO attachDetailVO = new AttachDetailVO();
//            attachDetailVO.setAttachKey(invoiceReg.getAccessory());
//            attachDetailVO = uploadUtil.addAttachUploadResult(attachDetailVO);
//            if (attachDetailVO == null || attachDetailVO.getDownloadUrl() == null)
//                throw new BaseException(invoiceReg.getInvoiceCode() + "附件信息不存在");

            /**
             * 转换详明
             */
            InvoiceRegDTO invoiceRegDTO = new InvoiceRegDTO();
            invoiceRegDTO.setInvoiceCode(invoiceReg.getInvoiceCode());
            invoiceRegDTO.setInvoiceMoney(invoiceReg.getInvoiceSum());
            invoiceRegDTO.setExpressNo(inParm.getTrackingNum());
            invoiceRegDTO.setInvoiceDate(invoiceReg.getInvoiceDate());
            invoiceRegDTO.setFileObj(invoiceReg.getAccessory() + "$");
            invoiceRegDTOS.add(invoiceRegDTO);
        });
        /*
         * 转换头信息
         */
        invoiceApplyDTO.setInsertList(invoiceRegDTOS);
        invoiceApplyDTO.setRequestId(invoiceApply.getInvoiceId());
        invoiceApplyDTO.setShipperName(invoiceApply.getCustomerName());
        /*
         * 同步数据
         */
        BmsServiceResult bmsServiceResult = otmUtil.invoiceToBmsService(invoiceApplyDTO);
        if (bmsServiceResult == null) {
            throw new BaseException("数据同步BMS失败");
        }
        if (!bmsServiceResult.isSuccess()) {
            throw new BaseException(bmsServiceResult.getMessage());
        }


        /*
         * 生成收款确认单
         */
        ReceiptAffirm receiptAffirm = new ReceiptAffirm();
        List<ReceiptAffirmDtl> receiptAffirmDtls = new ArrayList<>();
        receiptAffirm.setPayName(invoiceApply.getClient());
        receiptAffirm.setCreator(invoiceApply.getCreator());
        receiptAffirm.setEnteringDate(invoiceApply.getRegisterDate());
        receiptAffirm.setTenantId(invoiceApply.getTenantId());
        receiptAffirm.setSum(BigDecimal.ZERO);
        receiptAffirm.setDiffSum(BigDecimal.ZERO);
        receiptAffirm.setState(0);
        invoiceRegs.forEach(invoiceReg -> {
            ReceiptAffirmDtl receiptAffirmDtl = new ReceiptAffirmDtl();
            receiptAffirmDtl.setInvoiceId(invoiceReg.getId());
            receiptAffirmDtl.setInvoiceCode(invoiceReg.getInvoiceCode());
            receiptAffirmDtl.setInvoiceSum(invoiceReg.getInvoiceSum());
            receiptAffirmDtl.setUndeteSum(invoiceReg.getInvoiceLackSum());
            receiptAffirmDtl.setAccountSum(invoiceReg.getInvoiceReSum());
            receiptAffirmDtl.setDate(new Date());
            receiptAffirmDtls.add(receiptAffirmDtl);
        });

        receiptAffirmService.insertReceiptAffirm(receiptAffirm, receiptAffirmDtls, false);
    }

    /**
     * 无token根据开票申请id查询开票申请信息
     *
     * @param invoiceId
     * @return
     */
    @Override
    public InvoiceApply getInvoiceApplyByBmsInvoiceIdNoTenant(String invoiceId) {
        if (!StringUtils.isEmpty(invoiceId)) {
            // 根据开票申请id找对应的开票信息
            EntityWrapper<InvoiceApply> ew = new EntityWrapper<>();
            ew.eq("invoice_id", invoiceId);
            List<InvoiceApply> invoiceApplyList = baseMapper.selectInvoiceApplyNoTenant(ew);
            if (!CollectionUtils.isEmpty(invoiceApplyList)) {
                return invoiceApplyList.get(0);
            }
        }
        return null;
    }

    /**
     * 取消开票通知
     *
     * @param invoiceApply
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void cancleInvoiceApplyForBms(InvoiceApply invoiceApply) {
        // 1 - 校验
        if (Objects.isNull(invoiceApply)) {
            throw new BaseException("参数为空");
        }
        if (StringUtils.isEmpty(invoiceApply.getInvoiceId())) {
            throw new BaseException("开票申请id为空");
        }
        // 根据开票申请id找对应的开票信息
        InvoiceApply invoiceApplyNoTenant = this.getInvoiceApplyByBmsInvoiceIdNoTenant(invoiceApply.getInvoiceId());
        if (Objects.nonNull(invoiceApplyNoTenant)) {

            // 1. 删除主表信息
            this.deleteById(invoiceApplyNoTenant.getId());
            // 2. 删除明细数据
            batchDeleteDetail(invoiceApplyNoTenant.getId());
        }
    }

    /**
     * 根据条件导出数据
     *
     * @param condition
     * @return
     */
    @Override
    public List<InvoiceApplyExcelVO> exportInvoiceApplyDataByCondition(Map<String, Object> condition) {
        EntityWrapper<InvoiceApply> ew = this.bindInvoiceApplyEntityWrapper(condition);
        List<InvoiceApply> invoiceApplyList = this.selectList(ew);
        if (!CollectionUtils.isEmpty(invoiceApplyList)) {
            List<InvoiceApplyExcelVO> voList = Lists.newArrayList();
            invoiceApplyList.forEach(invoiceApply -> {
                InvoiceApplyExcelVO invoiceApplyExcelVO = new InvoiceApplyExcelVO();
                BeanUtils.copyProperties(invoiceApply, invoiceApplyExcelVO);
                // 创建时间
                if (Objects.nonNull(invoiceApply.getGmtCreate())) {
                    invoiceApplyExcelVO.setGmtCreateStr(ToolCommonUtils.getDateToStrFormat(invoiceApply.getGmtCreate()));
                }
                // 登记时间
                if (Objects.nonNull(invoiceApply.getRegisterDate())) {
                    invoiceApplyExcelVO.setRegisterDateStr(ToolCommonUtils.getDateToStrFormat(invoiceApply.getRegisterDate()));
                }
                // 审核时间
                if (Objects.nonNull(invoiceApply.getAuditDate())) {
                    invoiceApplyExcelVO.setAuditDateStr(ToolCommonUtils.getDateToStrFormat(invoiceApply.getAuditDate()));
                }
                // 计划收票时间
                if (Objects.nonNull(invoiceApply.getPlanReceiptDate())) {
                    invoiceApplyExcelVO.setPlanReceiptDateStr(ToolCommonUtils.getDateToStrFormat(invoiceApply.getPlanReceiptDate()));
                }
                // 状态 0-新增, 1-审核, 2-已结算
                if (Objects.nonNull(invoiceApply.getStatus())) {
                    if (Integer.valueOf(0).equals(invoiceApply.getStatus())) {
                        invoiceApplyExcelVO.setStatusStr("新增");
                    } else if (Integer.valueOf(1).equals(invoiceApply.getStatus())) {
                        invoiceApplyExcelVO.setStatusStr("审核");
                    } else if (Integer.valueOf(2).equals(invoiceApply.getStatus())) {
                        invoiceApplyExcelVO.setStatusStr("已结算");
                    } else if (Integer.valueOf(3).equals(invoiceApply.getStatus())) {
                        invoiceApplyExcelVO.setStatusStr("已确认");
                    }
                } else {
                    invoiceApplyExcelVO.setStatusStr("新增");
                }
                voList.add(invoiceApplyExcelVO);
            });
            return voList;

        }
        return null;
    }

    /**
     * 处理明细
     *
     * @param headId
     */
    private void batchDeleteDetail(Long headId) {
        // 开票信息关联的考核单
        this.dealDeleteInvoiceAssess(headId);

        // 账单明细
        invoiceApplyBillService.deleteInvoiceApplyBillByHeadId(headId);

        // 处理附件明细
        this.dealDeleteInvoiceAccy(headId);

        // 发票登记信息
        this.dealDeleteInvoiceReg(headId);
    }

    /**
     * 处理开票考核单
     *
     * @param headId
     */
    private void dealDeleteInvoiceAssess(Long headId) {
        // 开票信息关联的考核单
        List<InvoiceApplyAsse> invoiceApplyAssesList = invoiceApplyAsseService.selectInvoiceApplyAssessByHeadId(headId);
        if (!CollectionUtils.isEmpty(invoiceApplyAssesList)) {
            // 回退金额
            Map<String, BigDecimal> assessCodeSum = Maps.newHashMap();
            Map<String, BigDecimal> rewardCodeSum = Maps.newHashMap();
            invoiceApplyAssesList.stream()
                    .filter(invoiceApplyAsse -> !StringUtils.isEmpty(invoiceApplyAsse.getAssessCode()))
                    .forEach(invoiceApplyAsse -> {
                        if (Integer.valueOf(0).equals(invoiceApplyAsse.getType())) {
                            // 考核单
                            assessCodeSum.put(invoiceApplyAsse.getAssessCode(), invoiceApplyAsse.getCurUseMoney());
                        } else if (Integer.valueOf(1).equals(invoiceApplyAsse.getType())) {
                            // 奖励单
                            rewardCodeSum.put(invoiceApplyAsse.getAssessCode(), invoiceApplyAsse.getCurUseMoney());
                        }
                    });

            /**
             * 处理考核单
             */
            Set<String> assessCodeSet = assessCodeSum.keySet();
            if (!CollectionUtils.isEmpty(assessCodeSet)) {
                List<FeeAssessment> feeAssessmentList = feeAssessmentService.selectFeeAssessmentListByCodesNoTenant(assessCodeSet);
                if (!CollectionUtils.isEmpty(feeAssessmentList)) {
                    // 金额
                    feeAssessmentList.forEach(feeAssessment -> {
                        BigDecimal userMoney = assessCodeSum.get(feeAssessment.getAssessCode());
                        if (Objects.nonNull(userMoney)) {
                            feeAssessment.setBmsSum(feeAssessment.getBmsSum().subtract(userMoney));
                        }
                    });
                    // 更新
                    feeAssessmentService.updateBatchById(feeAssessmentList);
                }
            }

            /**
             * 处理奖励单
             */
            Set<String> rewardCodeSet = rewardCodeSum.keySet();
            if (!CollectionUtils.isEmpty(rewardCodeSet)) {
                List<FeeReward> feeRewardList = feeRewardService.selectFeeRewardListByCodes(rewardCodeSet);
                if (!CollectionUtils.isEmpty(feeRewardList)) {
                    feeRewardList.forEach(feeReward -> {
                        BigDecimal userMoney = rewardCodeSum.get(feeReward.getRedCode());
                        if (Objects.nonNull(userMoney)) {
                            feeReward.setBmsSum(feeReward.getBmsSum().subtract(userMoney));
                        }
                    });
                    // 更新
                    feeRewardService.updateBatchById(feeRewardList);
                }
            }
            // 考核明细
            invoiceApplyAsseService.deleteAssessDetailByHeadId(headId);
        }
    }

    /**
     * 处理附件明细
     *
     * @param headId
     */
    private void dealDeleteInvoiceAccy(Long headId) {
        // 附件
        List<InvoiceApplyAccy> invoiceApplyAccyList = invoiceApplyAccyService.selectInvoiceApplyAccyByHeadId(headId);
        if (!CollectionUtils.isEmpty(invoiceApplyAccyList)) {
            invoiceApplyAccyList.forEach(invoiceApplyAccy -> {
                // 删除七牛文件
                this.deleteQinniuFile(invoiceApplyAccy.getFileKey());
            });
            invoiceApplyAccyService.deleteInvoiceAccyByHeadId(headId);
        }
    }

    /**
     * 发票登记信息
     *
     * @param headId
     */
    private void dealDeleteInvoiceReg(Long headId) {
        List<InvoiceReg> invoiceRegList = invoiceRegService.selectInvoiceRegByHeadIdNoTenant(headId);
        if (!CollectionUtils.isEmpty(invoiceRegList)) {
            invoiceRegList.forEach(invoiceReg -> {
                // 删除七牛文件
                this.deleteQinniuFile(invoiceReg.getAccessory());
            });
        }
        invoiceRegService.deleteBatchByHeadId(headId);
    }

    /**
     * 删除七牛的文件
     *
     * @param fileKey
     */
    private void deleteQinniuFile(String fileKey) {
        try {
            if (!StringUtils.isEmpty(fileKey)) {
                FileInfo fileInfo = QiniuUtils.getFileInfo(fileKey);
                if (Objects.nonNull(fileInfo)) {
                    QiniuUtils.DeleteFile(fileKey);
                }
            }
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }
}
